<!DOCTYPE HTML>
<html>
<body>
<script src="/js-test-resources/js-test.js"></script>
<script>
description("Test that a cross-origin redirect does not result in a non-simple request being sent to the target.");

window.jsTestIsAsync = true;

function setImmediate(f)
{
    var channel = new MessageChannel();
    channel.port1.onmessage = function() { channel.port1.close(); f(); };
    channel.port2.postMessage("abusingmessagechannelsforfunandprofit");
    channel.port2.close();
}

function resetTripmine()
{
    var req = new XMLHttpRequest;
    req.open("GET", "/resources/reset-temp-file.php?filename=tripmine-status", false);
    req.send();
}

function fetchTripmineStatus()
{
    var req = new XMLHttpRequest;
    req.open("GET", "/resources/tripmine.php?command=status", false);
    req.send();
    return req.responseText;
}

function checkResult()
{
    window.tripmineStatus = fetchTripmineStatus();
    shouldBeEmptyString("tripmineStatus");
}

function testAsync(method, code)
{
    debug("Asynchronous XMLHttpRequest " + code + " " + method + " redirect:");

    var req = new XMLHttpRequest;

    setImmediate(function() {
        resetTripmine();
        req.open(method, "/resources/redirect.php?code=" + code + "&url=http://localhost:8000/resources/tripmine.php", true);
        req.setRequestHeader("X-WebKit-Test", "*");
        req.setRequestHeader("Content-Type", "application/xml");
        req.send("data");
    });

    return new Promise(function(resolve, reject)
    {
        req.onloadend = function() {
            setImmediate(function() {
                checkResult();
                resolve();
            });
        };
    });
}

function testSync(method, code)
{
    debug("Synchronous XMLHttpRequest " + code + " " + method + " redirect:");
    resetTripmine();

    var req = new XMLHttpRequest;
    req.open(method, "/resources/redirect.php?code=" + code + "&url=http://localhost:8000/resources/tripmine.php", false);
    req.setRequestHeader("X-WebKit-Test", "*");
    req.setRequestHeader("Content-Type", "application/xml");
    window.testSyncReq = req;
    shouldThrow("testSyncReq.send('data')");
    checkResult();
}

var ASYNC_TEST_CASES = [
    ["POST", 307],
    ["GET", 307],
    ["POST", 303],
    ["GET", 303],
    ["POST", 302],
    ["GET", 302],
    ["DELETE", 307],
    ["POST", 301],
    ["GET", 301],
    ["DELETE", 301],
];

var SYNC_TEST_CASES = [
    ["POST", 307],
    ["GET", 307],
    ["POST", 303],
    ["GET", 303],
    ["POST", 302],
    ["GET", 302],
    ["DELETE", 307],
    ["POST", 301],
    ["GET", 301],
    ["DELETE", 301],
];

function finish()
{
    resetTripmine();

    finishJSTest();
}

var prevPromise = Promise.resolve();
for (var i = 0; i < ASYNC_TEST_CASES.length; ++i) {
    var method = ASYNC_TEST_CASES[i][0];
    var code = ASYNC_TEST_CASES[i][1];
    prevPromise = prevPromise.then(testAsync.bind(null, method, code));
}
prevPromise.then(function()
{
    setImmediate(function() {
        try {
            for (var i = 0; i < SYNC_TEST_CASES.length; ++i) {
                var method = SYNC_TEST_CASES[i][0];
                var code = SYNC_TEST_CASES[i][1];
                testSync(method, code);
            }
        } catch (e) {
            testFailed(e.toString());
        }
        finish();
    });
});
</script>
